﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PloobsEngine.DataStructure;
using System.Xml.Serialization;

namespace Etapa1.ComercioEspacial
{
    [Serializable]
    public class CentroComercio
    {

        public void Initialize()
        {
            foreach (String item in disponiveis.Keys)
            {
                foreach (var prods in disponiveis[item])
                {
                    AddProdutoToSell(prods);    
                }
                
            }

            foreach (String item in necessidades.Keys)
            {
                foreach (var prods in necessidades[item])
                {
                    AddProdutoToBuy(prods);
                }

            }
        }

        public SerializableDictionary<String,List<Produto>> disponiveis = new SerializableDictionary<string,List<Produto>>();
        public SerializableDictionary<String, List<Produto>> necessidades = new SerializableDictionary<string, List<Produto>>();
        
        [XmlIgnoreAttribute]
        public Dictionary<String, PriorityQueueB<Produto>> produtosDisponiveis = new Dictionary<string, PriorityQueueB<Produto>>();
        [XmlIgnoreAttribute]
        public Dictionary<String, PriorityQueueB<Produto>> produtosNecessidades = new Dictionary<string, PriorityQueueB<Produto>>();

        public void AddProdutoToBuy(Produto prod)
        {            
            if (produtosNecessidades.ContainsKey(prod.nome))
            {
                produtosNecessidades[prod.nome].Push(prod);
            }
            else
            {
                produtosNecessidades[prod.nome] = new PriorityQueueB<Produto>(new comparador2());
                produtosNecessidades[prod.nome].Push(prod);
            }
            
        }

        public void AddProdutoToSell(Produto prod)
        {
            if (produtosDisponiveis.ContainsKey(prod.nome))
            {
                produtosDisponiveis[prod.nome].Push(prod);
            }
            else
            {
                produtosDisponiveis[prod.nome] = new PriorityQueueB<Produto>(new comparador1());
                produtosDisponiveis[prod.nome].Push(prod);
            }            
        }

        public int SellProduto(Agente agente, String nomeProduto, int Quantidade)
        {
            Produto p = produtosNecessidades[nomeProduto].Peek();
            if (p == null)
                return 0;
            if (Quantidade > p.quantidade)
            {
                int falta = Quantidade - p.quantidade;
                produtosNecessidades[nomeProduto].Pop();
                agente.dinheiro += p.preco * p.quantidade;
                return p.quantidade + SellProduto(agente, nomeProduto, falta);
            }
            else
            {
                if (p.quantidade == Quantidade)
                {
                    produtosNecessidades[nomeProduto].Pop();
                }
                else
                {
                    p.quantidade -= Quantidade;
                }
                agente.dinheiro += p.preco * Quantidade;
                return Quantidade;
            }

        }

        public int BuyProduto(Agente agente , String nomeProduto, int Quantidade)
        {
            Produto p = produtosDisponiveis[nomeProduto].Peek();
            if (p == null)
                return 0;
            if (Quantidade > p.quantidade)
            {
                int falta = Quantidade - p.quantidade;
                produtosDisponiveis[nomeProduto].Pop();
                agente.dinheiro -= p.preco * p.quantidade;
                return p.quantidade + BuyProduto(agente, nomeProduto, falta);
            }
            else
            {
                if (p.quantidade == Quantidade)
                {
                    produtosDisponiveis[nomeProduto].Pop();
                }
                else
                {
                    p.quantidade -= Quantidade;
                }
                agente.dinheiro -= p.preco * Quantidade;                
                return Quantidade; 
            }

        }

    }

    [Serializable]
    public class Produto
    {
        [System.ComponentModel.DefaultValueAttribute (null)]
        public String owner;
        public string nome;
        public int quantidade;
        [System.ComponentModel.DefaultValueAttribute (0)]
        public int preco;

        public Produto Clone()
        {
            Produto p = new Produto();
            p.quantidade = quantidade;
            p.preco = preco;
            p.owner = owner;
            p.nome = nome;
            return p;            
        }

    }

    public class comparador1 : IComparer<Produto> 
    {
        #region IComparer<Produto> Members

        public int Compare(Produto x, Produto y)
        {
            if (x.preco > y.preco)
                return 1;
            else if (x.preco < y.preco)
                return -1;
            return 0;
        }

        #endregion
    }

    public class comparador2 : IComparer<Produto>
    {
        #region IComparer<Produto> Members

        public int Compare(Produto x, Produto y)
        {
            if (x.preco > y.preco)
                return -1;
            else if (x.preco < y.preco)
                return 1;
            return 0;
        }

        #endregion
    }


}
